package main

import (
	"encoding/base64"
	json2 "encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

type Post struct {
	User    string
	Threads []string
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/headers", testHeaders)
	http.HandleFunc("/body", testBody)
	http.HandleFunc("/process", process)
	http.HandleFunc("/upload", parseFile)
	http.HandleFunc("/write", writeExample)
	http.HandleFunc("/writeheader", writeHeaderExample)
	http.HandleFunc("/redirect", headExample)
	http.HandleFunc("/json", jsonExample)
	http.HandleFunc("/cookie", setCookie)
	http.HandleFunc("/get-cookie", getCookie)
	http.HandleFunc("/setmsg", setMsg)
	http.HandleFunc("/getmsg", showMsg)
	http.HandleFunc("/templ", tespExample)
	server.ListenAndServe()
}

func testHeaders(w http.ResponseWriter, r *http.Request) {
	h := r.Header
	//fmt.Println(h)
	fmt.Fprintln(w, h)

}
func testBody(w http.ResponseWriter, r *http.Request) {
	l := r.ContentLength
	body := make([]byte, l)
	r.Body.Read(body)
	fmt.Println(string(body))
	fmt.Fprintln(w, string(body))
}
func process(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	fmt.Println("1", r.FormValue("hello"))
	fmt.Println("2", r.PostFormValue("hello"))
	fmt.Println("3", r.Form)
	fmt.Println("4", r.PostForm)
	fmt.Fprintln(w, r.Form)
}
func parseFile(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1024)
	fileHeader := r.MultipartForm.File["upload"][0]
	file, err := fileHeader.Open()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()
	data, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Println(err)
		return
	}

	name := fileHeader.Filename
	fmt.Println("---------------->", name)
	create, err := os.Create(name)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer create.Close()
	_, err = create.Write(data)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Fprintln(w, string(data))

}
func writeExample(w http.ResponseWriter, r *http.Request) {
	str := `<html>
<head><title>GO WEB Programing</title></head>
<body><h1>Hello Word</h1></body>
</html>
`
	w.Write([]byte(str))
}
func writeHeaderExample(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(501)
	fmt.Fprintln(w, "no such service, try next door")
}
func headExample(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Location", "https://www.baidu.com/")
	w.WriteHeader(302)
}
func jsonExample(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	post := &Post{
		User:    "HHHHH",
		Threads: []string{"first", "second", "third"},
	}
	json, _ := json2.Marshal(post)
	w.Write(json)
}
func setCookie(w http.ResponseWriter, r *http.Request) {
	cl := http.Cookie{
		Name:       "my_cookie",
		Value:      "hhhhhhhhh",
		Path:       "",
		Domain:     "",
		Expires:    time.Time{},
		RawExpires: "",
		MaxAge:     0,
		Secure:     false,
		HttpOnly:   true,
		SameSite:   0,
		Raw:        "",
		Unparsed:   nil,
	}
	c2 := http.Cookie{
		Name:       "sec_cookie",
		Value:      "mmmmmmmmm",
		Path:       "",
		Domain:     "",
		Expires:    time.Time{},
		RawExpires: "",
		MaxAge:     0,
		Secure:     false,
		HttpOnly:   true,
		SameSite:   0,
		Raw:        "",
		Unparsed:   nil,
	}
	/*	w.Header().Set("Set-Cookie",cl.String())
		w.Header().Add("Set-Cookie",c2.String())*/
	http.SetCookie(w, &cl)
	http.SetCookie(w, &c2)
}
func getCookie(w http.ResponseWriter, r *http.Request) {
	h := r.Header["Cookie"]
	fmt.Fprintln(w, h)
}
func setMsg(w http.ResponseWriter, r *http.Request) {
	msg := []byte("hello world")
	c := http.Cookie{
		Name:  "flash",
		Value: base64.URLEncoding.EncodeToString(msg),
	}
	http.SetCookie(w, &c)
}
func showMsg(w http.ResponseWriter, r *http.Request) {
	c, err := r.Cookie("flash")
	if err != nil {
		if err == http.ErrNoCookie {
			fmt.Fprintln(w, "no message found")
		}
	} else {
		rc := http.Cookie{
			Name:       "flash",
			Value:      "",
			Path:       "",
			Domain:     "",
			Expires:    time.Unix(1, 0),
			RawExpires: "",
			MaxAge:     -1,
			Secure:     false,
			HttpOnly:   false,
			SameSite:   0,
			Raw:        "",
			Unparsed:   nil,
		}
		http.SetCookie(w, &rc)
		val, _ := base64.URLEncoding.DecodeString(c.Value)
		fmt.Fprintln(w, string(val))
	}
}
func tespExample(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("templ.html")
	if err != nil {
		fmt.Println(err)
		return
	}
	t.Execute(w, "hello word")
}
